package cn.xinfei.xdecision.data.core.frame.executors.collect.handler;

import cn.xinfei.xdecision.common.model.datax.datamanage.v2.Variable;
import cn.xinfei.xdecision.common.model.datax.enums.VariableEnum;
import cn.xinfei.xdecision.common.service.datax.datamanage.v2.VariableService;
import cn.xinfei.xdecision.data.core.cache.VarMetaDataCache;
import cn.xinfei.xdecision.data.core.frame.executors.VarContext;
import cn.xinfei.xdecision.data.core.frame.executors.collect.VarHandler;
import cn.xinfei.xdecision.data.core.frame.executors.collect.VariableHelper;
import cn.xinfei.xdecision.data.core.vo.VarCollectAwareVO;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.compress.utils.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class VarBasicAndConstHandler implements VarHandler<VarCollectAwareVO> {

    @Autowired
    VariableService variableService;

    @Autowired
    VarMetaDataCache varMetaDataCache;

    @Override
    public void doHandle(VarContext<VarCollectAwareVO> context) {
        VarCollectAwareVO varCollectAwareVO = context.get();
        Set<String> varCodes = varCollectAwareVO.getVarCodes();
        Map<String, Object> executorResultMap = varCollectAwareVO.getExecutorResultMap();
        Map<String, Object> inputPrarams = varCollectAwareVO.getInputPrarams();

        Optional<Map<String, Variable>> varMetaDataCache = Optional.ofNullable(
                this.varMetaDataCache.loadVarMetaData());
        List<Variable> variableList;
        if (varMetaDataCache.isPresent()) {
            log.info("requestId = {} VarBasicAndConstHandler 查询缓存 VarMetaDataCache！", varCollectAwareVO.getRequestId());
            variableList = varMetaDataCache.get().values().stream()
                    .filter(var -> varCodes.contains(var.getVarCode()))
                    .collect(Collectors.toList());
        } else {
            variableList = variableService.findVariables(varCodes);
        }

        HashMap<String, Object> constVarResult = variableList.stream()
                .filter(var -> Integer.valueOf(VariableEnum.CONSTANT_VAR.getCode()).equals(var.getVarType()))
                .collect(HashMap::new, (map, entry) -> map.put(entry.getVarCode(), VariableHelper.getConstValue(entry)), HashMap::putAll);

        HashMap<String, Object> basicVarResult = variableList.stream()
                .filter(var -> Integer.valueOf(VariableEnum.BASIC_VAR.getCode()).equals(var.getVarType()))
                .filter(var -> inputPrarams.containsKey(var.getVarCode()))
                .collect(HashMap::new, (map, entry) -> map.put(entry.getVarCode(), inputPrarams.get(entry.getVarCode())), HashMap::putAll);

        if (MapUtils.isNotEmpty(basicVarResult)) {
            executorResultMap.putAll(basicVarResult);
            List<String> basicVars = new ArrayList<>(basicVarResult.keySet());
            varCodes.removeAll(basicVars);
        }
        if (MapUtils.isNotEmpty(constVarResult)) {
            executorResultMap.putAll(constVarResult);
            List<String> constVars = new ArrayList<>(constVarResult.keySet());
            varCodes.removeAll(constVars);
        }

        if (MapUtils.isNotEmpty(executorResultMap)) {
            varCollectAwareVO.setExecutorResultMap(executorResultMap);
            varCollectAwareVO.setVarCodes(varCodes);
            varCollectAwareVO.setInputPrarams(new JSONObject(inputPrarams));
            context.setContext(varCollectAwareVO);
        }

    }
}
